import {
    Scene,
    PerspectiveCamera,
    WebGLRenderer,
    AmbientLight,
    AxesHelper,
    TextureLoader,
    MeshBasicMaterial,
    LineBasicMaterial,
    Line,
    Geometry,
    Curve,
    Shape,
    ExtrudeGeometry,
    BoxGeometry,
    Mesh,
    Vector3,
    Vector2,
    CatmullRomCurve3,
    BufferGeometry,
    SphereGeometry,
    TubeBufferGeometry,
    BufferAttribute,
    ShaderMaterial,
    UniformsUtils,
    UniformsLib,
    VertexColors,
    Color,
    Float32BufferAttribute,
    LineDashedMaterial,
    FogExp2,
    Object3D,
    MeshLambertMaterial,
    DirectionalLight,
    CylinderGeometry


} from "three";

import Stats from 'three/examples/jsm/libs/stats.module.js';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js';
import {GUI} from 'three/examples/jsm/libs/dat.gui.module.js';

//发光效果模块导入
import {EffectComposer} from 'three/examples/jsm/postprocessing/EffectComposer.js';
import {RenderPass} from 'three/examples/jsm/postprocessing/RenderPass.js';
import {UnrealBloomPass} from "three/examples/jsm/postprocessing/UnrealBloomPass.js";
import {ShaderPass} from "three/examples/jsm/postprocessing/ShaderPass.js";

import {LineGeometry} from 'three/examples/jsm/lines/LineGeometry.js';
import {LineMaterial} from 'three/examples/jsm/lines/LineMaterial.js';
import {Line2} from 'three/examples/jsm/lines/Line2.js';
import {GeometryUtils} from 'three/examples/jsm/utils/GeometryUtils.js';

import {CSS2DRenderer, CSS2DObject} from 'three/examples/jsm/renderers/CSS2DRenderer.js';


let container, stats, controls;
let camera, scene, renderer, bactex, axehelper, labelRenderer;

//测试变量
let API = {
    x: 0.1,
    y: 0.1,
    z: 0.1
};
let sphere;
let bloomComposer, finalComposer;
let materials = [];


let car, a = 0, Div, carlabel, cararrive = false; //car为汽车1，a为0-1的浮点数用于控制汽车1位置
let car2, a2 = 0, car2label, car2arrive = false; //汽车2
let car3, a3 = 0, car3label, car3arrive = false; //汽车3
let car4, a4 = 0, car4label, car4arrive = false; //汽车4
let car5, a5 = 0, car5label, car5arrive = false; //汽车5
let car6, a6 = 0, car6label, car6arrive = false; //汽车6

let tax, ta = 0; //汽车6

let scale = 0;

let shaderMaterial, uniform,magicSphereG,verticesRandom,magicSphere,randomColor,randomColor2;

init();
addShaderObjects();
animate();

function init() {
    // console.log('66667776');

    // 基础场景布置自调用函数
    (function SceneAdd() {
        container = document.createElement('div');
        document.body.appendChild(container);

        //基础场景布置
        scene = new Scene();
        bactex = new TextureLoader().load('./src/img/bac.png');
        scene.background = bactex;
        scene.fog = new FogExp2(0x04142a, 0.005);

        //添加环境光
        let light = new AmbientLight(0x404040); // soft white light
        scene.add(light);
        let directionalLight = new DirectionalLight(0xffffff, 1.5);
        scene.add(directionalLight);

        //添加相机
        camera = new PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 2000);
        camera.position.set(9.7, 2.14, -2.27517);
        camera.lookAt(new Vector3(-0.39, 0, 5.57));

        //基础渲染器
        renderer = new WebGLRenderer({antialias: true});
        // renderer.sortObjects = false;
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.gammaOutput = false;
        container.appendChild(renderer.domElement);

        //css渲染器
        labelRenderer = new CSS2DRenderer();
        labelRenderer.setSize(window.innerWidth, window.innerHeight);
        labelRenderer.domElement.style.position = 'absolute';
        labelRenderer.domElement.style.top = '0';
        container.appendChild(labelRenderer.domElement);

        stats = new Stats();
        container.appendChild(stats.dom);

        controls = new OrbitControls(camera, labelRenderer.domElement);
        controls.target.set(-0.39, 0, 5.57);
        controls.enableDamping = true; // 开启控制阻尼
        controls.dampingFactor = 0.05; //阻尼强度
        controls.screenSpacePanning = false;
        //相机控制位置限制
        // controls.minDistance = 20;
        // controls.maxDistance = 50;
        // controls.maxPolarAngle = Math.PI / 2.25;
        // controls.update();

        //坐标轴辅助
        // axehelper = new AxesHelper(5000);
        // // scene.add(axehelper);

        window.addEventListener('resize', onWindowResize, false);

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        //基础场景布置完毕
    })();

    //后期处理
    (function () {
        //发光效果 后期处理
        /**定义bloom发光特效合成器，不输出到屏幕*/
        bloomComposer = new EffectComposer(renderer);
        bloomComposer.renderToScreen = false;
        //初始渲染过程，（位于开始，渲染好的场景作为输入）
        let renderScene = new RenderPass(scene, camera);
        //bloom发光过程
        let bloomPass = new UnrealBloomPass(new Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85);
        //发光临界值
        bloomPass.threshold = 0;
        //发光强度
        bloomPass.strength = 1;
        //发光半径
        bloomPass.radius = 0;
        //bloom发光特效合成器添加过程链（原始，发光过程）
        bloomComposer.addPass(renderScene);
        bloomComposer.addPass(bloomPass);


        /**finalPass自定义着色器处理过程，材质处理*/
        let finalPass = new ShaderPass(
            new ShaderMaterial({
                uniforms: {
                    baseTexture: {value: null},
                    bloomTexture: {value: bloomComposer.renderTarget2.texture}
                },
                vertexShader: document.getElementById('vertexshader').textContent,
                fragmentShader: document.getElementById('fragmentshader').textContent,
                defines: {}
            }), "baseTexture"
        );
        finalPass.needsSwap = true;
        //最终特效合成器（原始场景，最终过程处理）
        finalComposer = new EffectComposer(renderer);
        finalComposer.addPass(renderScene);
        finalComposer.addPass(finalPass);
    })();


    //辅助定位球（用于控制显示场景中的坐标）
    let geometry2 = new SphereGeometry(0.0000001, 32, 32);
    let material2 = new MeshBasicMaterial({color: 0xffff00});
    sphere = new Mesh(geometry2, material2);
    // scene.add(sphere);


    //添加路名显示
    let roadnamem = new MeshBasicMaterial({color: 0xffff00});
    let zhonglum = new Mesh(geometry2, roadnamem);
    zhonglum.position.z = -88;
    scene.add(zhonglum);
    let Div = document.createElement('div');
    Div.className = 'roadname';
    Div.textContent = '长江中路';
    let doorLabel = new CSS2DObject(Div);
    // doorLabel.position.set(0, 0.01, 0);
    zhonglum.add(doorLabel);

    let zhonglum2 = new Mesh(geometry2, roadnamem);
    zhonglum2.position.z = 88;
    scene.add(zhonglum2);
    let Div2 = document.createElement('div');
    Div2.className = 'roadname';
    Div2.textContent = '长江中路';
    let doorLabel2 = new CSS2DObject(Div2);
    // doorLabel2.position.set(0, 0.01, 0);
    zhonglum2.add(doorLabel2);

    let zhonglum3 = new Mesh(geometry2, roadnamem);
    zhonglum3.position.x = 83;
    scene.add(zhonglum3);
    let Div3 = document.createElement('div');
    Div3.className = 'roadname';
    Div3.textContent = '前进中路';
    let doorLabel3 = new CSS2DObject(Div3);
    zhonglum3.add(doorLabel3);

    let zhonglum4 = new Mesh(geometry2, roadnamem);
    zhonglum4.position.x = -83;
    scene.add(zhonglum4);
    let Div4 = document.createElement('div');
    Div4.className = 'roadname';
    Div4.textContent = '前进中路';
    let doorLabel4 = new CSS2DObject(Div4);
    zhonglum4.add(doorLabel4);


    // gui
    let gui = new GUI({width: 300});
    gui.add(API, 'x', -200, 200)
        .listen()
        .onChange(function () {
            sphere.position.x = API.x;
        });
    gui.add(API, 'y', -3, 3)
        .listen()
        .onChange(function () {
            sphere.position.y = API.y;
        });
    gui.add(API, 'z', -200, 200)
        .listen()
        .onChange(function () {
            sphere.position.z = API.z;
        });
    gui.close();


    //地面加载
    let loader = new GLTFLoader();
    loader.load('./src/model/add11.glb', function (gltf) {
        console.log(gltf);

        gltf.scene.traverse(function (child) {
            if (child.isMesh) {
                switch (child.name) {
                    case 'Door':
                        let doorDiv = document.createElement('div');
                        doorDiv.className = 'target';
                        doorDiv.textContent = '科博馆站';
                        let doorLabel = new CSS2DObject(doorDiv);
                        doorLabel.position.set(0, 0.01, 0);
                        // bowuguan = child;
                        child.add(doorLabel);
                        console.log(child);
                        // child.material = new MeshBasicMaterial({
                        //     color: 0x3c78b4,
                        //     transparent: true, opacity: 0.4
                        // });
                        // child.add(magicSphere);


                        break;
                    case 'ground':
                        child.material = new MeshBasicMaterial({color: 0x051129});
                        child.position.y -= 1;
                        break;
                    // case 'River':
                    //     child.material = new MeshBasicMaterial({color: 0x002c61});
                    //     break;
                    case 'Road1':
                    case 'Road2':
                    case 'Road3':
                    case 'Road4':
                        child.material = new MeshBasicMaterial({color: new Color("rgb(40,82,122)")});
                        break;
                    default:
                        child.material = new MeshBasicMaterial({
                            color: 0x3c78b4,
                            transparent: true, opacity: 0.4
                        });
                        break;
                }

            }
        });

        scene.add(gltf.scene);
    });

    //汽车加载
    loader.load('./src/model/carmodi3.glb', function (gltf) {
        console.log(gltf);

        //创建一个新的汽车材质
        let material = new MeshLambertMaterial({color: 0x006600});


        //汽车位置更新
        gltf.scene.children[0].position.set(0, 0, 0);
        //将汽车场景保存为一个变量
        gltf.scene.children[0].add(gltf.scene.children[1]);
        //汽车模型放大缩小
        gltf.scene.children[0].scale.set(1 / 10, 1 / 10, 1 / 10);
        //汽车材质更新

        gltf.scene.traverse(function (child) {
            if (child.isMesh) {
                child.material = material;
            }
        });


        car = gltf.scene.children[0];
        scene.add(car);

        car2 = car.clone(true);
        car3 = car.clone(true);
        car4 = car.clone(true);
        scene.add(car2);
        scene.add(car3);
        scene.add(car4);

        //汽车头顶信息显示，earthLabel为css元素555
        Div = document.createElement('div');
        Div.className = 'label';
        Div.textContent = '1号';
        carlabel = new CSS2DObject(Div);
        carlabel.position.set(0, 0.1, 0);
        car.add(carlabel);

        //汽车头顶信息显示，earthLabel为css元素555
        let earthDiv = document.createElement('div');
        earthDiv.className = 'label';
        earthDiv.textContent = '2号';
        car2label = new CSS2DObject(earthDiv);
        car2label.position.set(0, 0.1, 0);
        car2.add(car2label);

        //汽车头顶信息显示，earthLabel为css元素555
        earthDiv = document.createElement('div');
        earthDiv.className = 'label';
        earthDiv.textContent = '3号';
        car3label = new CSS2DObject(earthDiv);
        car3label.position.set(0, 0.1, 0);
        car3.add(car3label);

        //汽车头顶信息显示，earthLabel为css元素555
        earthDiv = document.createElement('div');
        earthDiv.className = 'label';
        earthDiv.textContent = '4号';
        car4label = new CSS2DObject(earthDiv);
        car4label.position.set(0, 0.1, 0);
        car4.add(car4label);


    });


    //出租车加载
    loader.load('./src/model/taxi2.glb', function (gltf) {


        //创建一个新的汽车材质
        let material = new MeshLambertMaterial({color: 0x006600});


        //汽车位置更新
        gltf.scene.children[1].position.set(0, 0, 10);

        //汽车模型放大缩小
        gltf.scene.children[1].scale.set(1 / 10, 1 / 10, 1 / 10);
        //汽车材质更新

        gltf.scene.traverse(function (child) {
            if (child.isMesh) {
                child.material = material;
            }
        });


        tax = gltf.scene.children[1];
        scene.add(tax);

    });


    //////////////////////////// 线路1。。。。。。。。。。。。。。。。。
    let cur = new CatmullRomCurve3([
        new Vector3(-1.33, 0, 170),
        new Vector3(-1.29, 0, 90),
        new Vector3(-1.25, 0, 22),
        new Vector3(-1.25, 0, 2.6),
        new Vector3(2.1, 0, 2.6),
        new Vector3(32.27, 0, 2.6),
        new Vector3(150, 0, 3.3),
    ]);
    //创建线路3，其中radius为线路的半径
    let road_g = new TubeBufferGeometry(cur, 10000, 0.01, 8, false);
    let road_m = new MeshBasicMaterial({color: 0x05E9E2});
    let road = new Mesh(road_g, road_m);
    //指定名称，便于发光渲染器发光处理
    // road.name = 'lightline';
    // scene.add( road );

    //汽车运动定时回调
    function carRun() {
        let run = setInterval(function () {
            //a3增加大小控制汽车运动速度
            a += 0.00033;
            if (car) {

                //汽车走完全程，汽车位置重置
                if (a > 1) {
                    a = 0;
                    cararrive = false;
                    Div.textContent = '1号';
                    car.children[0].name = 'body';
                    let material = new MeshLambertMaterial({color: 0x006600});
                    car.traverse(function (child) {
                        if (child.isMesh) {
                            child.material = material;
                        }
                    });
                    car.add(carlabel);
                }

                //汽车3位置更新，方向更新
                cur.getPoint(a, car.position);
                if (cararrive === false && car.position.x > 32.27 && car.position.x < 34) {
                    console.log('汽车1到站');
                    cararrive = true;
                    clearInterval(run);
                    setTimeout(carleafRun, 2000);

                }

                car.position.y = 0;
                car.lookAt(cur.getPoint(a + 0.001).x, 0, cur.getPoint(a + 0.001).z);
            }
        }, 33);
    }

    carRun();

    function carleafRun() {
        car.children[0].name = 'nolightbody';
        car.remove(carlabel);
        carRun();
    }


    //////////////////////////// 线路2。。。。。。。。。。。。。。。。。。。。
    let cur2 = new CatmullRomCurve3([
        new Vector3(-200, 0, 1.3),
        new Vector3(153, 0, 3.4),
    ]);
    //创建线路3，其中radius为线路的半径
    let road2_g = new TubeBufferGeometry(cur2, 10000, 0.01, 8, false);
    let road2_m = new MeshBasicMaterial({color: 0x05E9E2});
    let road2 = new Mesh(road2_g, road2_m);
    //指定名称，便于发光渲染器发光处理
    road2.name = 'lightline';
    // scene.add( road2 );

    //汽车运动定时回调
    function carRun2() {
        let run2 = setInterval(function () {
            //a3增加大小控制汽车运动速度
            a2 += 0.00033;
            if (car2) {

                //汽车走完全程，汽车位置重置
                if (a2 > 1) {
                    a2 = 0;
                    car2arrive = false;
                    car2.children[0].name = 'body';
                    car2.add(car2label);
                }

                //汽车3位置更新，方向更新
                cur2.getPoint(a2, car2.position);
                if (car2arrive === false && car2.position.x > 32.27 && car2.position.x < 34) {
                    console.log('汽车2到站');
                    car2arrive = true;
                    clearInterval(run2);
                    setTimeout(carleafRun2, 2000);

                }

                car2.position.y = 0;
                car2.lookAt(cur2.getPoint(a2 + 0.001).x, 0, cur2.getPoint(a2 + 0.001).z);
            }
        }, 33);
    }

    carRun2();
    function carleafRun2() {
        car2.children[0].name = 'nolightbody';
        car2.remove(car2label);
        carRun2();
    }


    //////////////////////////// 线路3。。。。。。。。。
    let cur3 = new CatmullRomCurve3([
        new Vector3(-1.42, 0, -176),
        new Vector3(-1.42, 0, -0.71),
        new Vector3(-1.25, 0, 2.8),
        new Vector3(2, 0, 2.8),
        new Vector3(153, 0, 3.4),
    ]);
    //创建线路3，其中radius为线路的半径
    let road3_g = new TubeBufferGeometry(cur3, 10000, 0.01, 8, false);
    let road3_m = new MeshBasicMaterial({color: 0x05E9E2});
    let road3 = new Mesh(road3_g, road3_m);
    //指定名称，便于发光渲染器发光处理
    road3.name = 'lightline';
    // scene.add( road3 );

    //汽车运动定时回调
    function carRun3() {
        let run3 = setInterval(function () {
            //a3增加大小控制汽车运动速度
            a3 += 0.0005;
            if (car3) {

                //汽车走完全程，汽车位置重置
                if (a3 > 1) {
                    a3 = 0;
                    car3arrive = false;
                    car3.children[0].name = 'body';
                    car3.add(car3label);
                }

                //汽车3位置更新，方向更新
                cur3.getPoint(a3, car3.position);
                if (car3arrive === false && car3.position.x > 32.27 && car3.position.x < 34) {
                    console.log('汽车3到站');
                    car3arrive = true;
                    clearInterval(run3);
                    setTimeout(carleafRun3, 2000);

                }

                car3.position.y = 0;
                car3.lookAt(cur3.getPoint(a3 + 0.001).x, 0, cur3.getPoint(a3 + 0.001).z);
            }
        }, 33);
    }

    carRun3();

    function carleafRun3() {
        car3.children[0].name = 'nolightbody';
        car3.remove(car3label);
        carRun3();
    }


    //////////////////////////// 线路4。。。。。。。。。
    let cur4 = new CatmullRomCurve3([
        new Vector3(2, 0, -183),
        new Vector3(2, 0, -0.71),
        new Vector3(2, 0, 2.8),
        new Vector3(4, 0, 2.8),
        new Vector3(153, 0, 3.4),
    ]);
    //创建线路3，其中radius为线路的半径
    let road4_g = new TubeBufferGeometry(cur4, 10000, 0.01, 8, false);
    let road4_m = new MeshBasicMaterial({color: 0x05E9E2});
    let road4 = new Mesh(road4_g, road4_m);
    //指定名称，便于发光渲染器发光处理
    road4.name = 'lightline';
    // scene.add( road4 );

    //汽车运动定时回调
    function carRun4() {
        let run4 = setInterval(function () {
            //a3增加大小控制汽车运动速度
            if (a4 > 0.25 && a4 < 0.75) {
                // console.log('car4到达路口');
                a4 += 0.002;
            } else {
                a4 += 0.0001;
            }
            // a4 += 0.001;
            if (car4) {

                //汽车走完全程，汽车位置重置
                if (a4 > 1) {
                    a4 = 0;
                    car4arrive = false;
                    car4.children[0].name = 'body';
                    car4.add(car4label);
                }

                //汽车3位置更新，方向更新
                cur4.getPoint(a4, car4.position);
                if (car4arrive === false && car4.position.x > 32.27 && car4.position.x < 34) {
                    console.log('汽车4到站');
                    car4arrive = true;
                    clearInterval(run4);
                    setTimeout(carleafRun4, 2000);

                }

                car4.position.y = 0;
                car4.lookAt(cur4.getPoint(a4 + 0.001).x, 0, cur4.getPoint(a4 + 0.001).z);
            }
        }, 33);
    }

    carRun4();

    function carleafRun4() {
        car4.children[0].name = 'nolightbody';
        car4.remove(car4label);
        carRun4();
    }

    window.addEventListener("keydown", function (event) {
        console.log(a4);
    });


    setInterval(function () {
        console.log('a4的值为: ' + a4);
        if (a4 < 0.18) {
            console.log('距离a4到站还有 1 分钟！');
        }
        if (a4 > 0.5 && a4 < 0.83) {
            console.log('a4 已到站！！！');
        }

    }, 60000);

    //////////////////////////// 出租车线路1。。。。。。。。。
    let tcur = new CatmullRomCurve3([
        new Vector3(153, 0, 3.4),
        new Vector3(4, 0, 2.8),
        new Vector3(2, 0, 2.8),
        new Vector3(2, 0, -0.71),
        new Vector3(2, 0, -183),
    ]);
    //创建线路3，其中radius为线路的半径
    let troad_g = new TubeBufferGeometry(tcur, 10000, 0.01, 8, false);
    let troad_m = new MeshBasicMaterial({color: 0x05E9E2});
    let troad = new Mesh(troad_g, troad_m);
    //指定名称，便于发光渲染器发光处理
    troad.name = 'lightline';
    // scene.add( troad );

    //汽车运动定时回调
    function tcarRun() {
        setInterval(function () {
            //a3增加大小控制汽车运动速度
            if (tax.position.x < 5 && tax.position.x > -5 && tax.position.z < 5 && tax.position.z > -2) {
                console.log('出租车到达路口');
                ta += 0.005;
            } else {
                ta += 0.001;
            }

            if (tax) {
                // console.log(tax);

                //汽车走完全程，汽车位置重置
                if (ta > 1) {
                    ta = 0;
                }
                tcur.getPoint(ta, tax.position);
                tax.position.y = 0.4;
                tax.lookAt(tcur.getPoint(ta + 0.001).x, 0.4, tcur.getPoint(ta + 0.001).z);
            }
        }, 33);
    }

    tcarRun();

    setInterval(function () {
        console.log(car);
        Div.textContent = '无座';
        let material = new MeshLambertMaterial({color: 0xDE0013});
        car.traverse(function (child) {
            if (child.isMesh) {
                child.material = material;
            }
        })
    }, 70000)


}

function addShaderObjects() {

    let radius = 10.0;
    let height = 20;
    uniform = {
        topColor: {value: new Color('rgba(92,183,255,0.54)')},
        bottomColor: {value: new Color('green')},
        radius:{value:radius},
        opa:{value:0},
    };

    shaderMaterial = new ShaderMaterial({

        uniforms: UniformsUtils.merge([UniformsLib["lights"], uniform]),
        vertexShader: document.getElementById('vertexshader2').textContent,
        fragmentShader: document.getElementById('fragmentshader2').textContent,
        transparent:true,
        // fog:true,
        // wireframe:true

    });
    shaderMaterial.lights = true;
    shaderMaterial.side = 2;

    magicSphereG = new CylinderGeometry( radius, radius, height, 50 );
    // magicSphereG.renderOrder = -100;
    magicSphereG.faces.splice(0,50 * 3);
    magicSphere = new Mesh(magicSphereG, shaderMaterial);
    scene.add(magicSphere);
    magicSphere.position.set(32,height / 2 + 1,4.8);


}

function changeShaderMaterial() {

    if(scale >= 5){
        scale = 0;
    }
    scale += 0.04;
    shaderMaterial.uniforms.opa.value = 5 - scale;
    magicSphere.scale.set(scale,1,scale);
}

function animate() {

    changeShaderMaterial();

    requestAnimationFrame(animate);
    stats.update();
    controls.update();


    //发光效果渲染
    scene.background = null;
    let darkMaterial = new MeshBasicMaterial({color: "black"});
    scene.traverse(function (child) {
        if (child.name !== 'body' && child.name !== 'RoadB' && child.name !== 'lightline') {
            materials[child.uuid] = child.material;
            child.material = darkMaterial;
        }

    });
    bloomComposer.render();
    //寻找场景中名称指定的非发光物体
    scene.traverse(function (child) {
        if (child.name !== 'body' && child.name !== 'RoadB' && child.name !== 'lightline') {
            child.material = materials[child.uuid];
        }
    });
    scene.background = bactex;
    //发光后期渲染器渲染
    finalComposer.render();

    //css渲染器渲染
    labelRenderer.render(scene, camera);
}
